package com.aivin.lint_lib_java.detector;

import com.aivin.lint_lib_java.JavaLog;
import com.android.tools.lint.client.api.UElementHandler;
import com.android.tools.lint.detector.api.Category;
import com.android.tools.lint.detector.api.Detector;
import com.android.tools.lint.detector.api.Implementation;
import com.android.tools.lint.detector.api.Issue;
import com.android.tools.lint.detector.api.JavaContext;
import com.android.tools.lint.detector.api.Scope;
import com.android.tools.lint.detector.api.Severity;
import com.android.tools.lint.detector.api.TextFormat;
import com.intellij.psi.PsiMethod;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.uast.UCallExpression;
import org.jetbrains.uast.UElement;
import org.jetbrains.uast.util.UastExpressionUtils;

import java.util.Collections;
import java.util.List;


public class AVToastDetector extends Detector implements Detector.UastScanner {

    public static final Issue ISSUE = Issue.create(
            "Aivin_ToastIssue", // IssueId ,当前 Issue的ID
            "吐司使用不规范", // 简单描述当前问题
            "为了统一风格，禁止使用系统吐司", // 详细解释当前问题和修复建议
            Category.CORRECTNESS, //  问题类别
            9, // 优先级，从1到10，10最重要
            Severity.ERROR, // 警报级别  FATAL（奔溃）, ERROR（错误）, WARNING（警告）,INFORMATIONAL（信息性）,IGNORE（可忽略）
            new Implementation( AVToastDetector.class, Scope.JAVA_FILE_SCOPE) // Issue和哪个Detector绑定，以及声明检查的范围。
    );

    /**
     * 返回我们 需要检测的类，这里返回的类都被会检查
     */
    @Override
    public List<Class<? extends UElement>> getApplicableUastTypes() {
        return Collections.singletonList( UCallExpression.class);
    }

    /**
     * 替换成 自定义 处理器
     */
    @Override
    public UElementHandler createUastHandler(@NotNull JavaContext context) {
        return new LogHandler(context);
    }

    class LogHandler extends UElementHandler {
        private JavaContext context;

        LogHandler(JavaContext context) {
            this.context = context;
        }

        @Override
        public void visitCallExpression( @NotNull UCallExpression node) {
            if (!UastExpressionUtils.isMethodCall(node)) {
                return;
            }

            if (node.getReceiver() == null ||  node.getMethodName() == null){
                return;
            }

            String methodName = node.getMethodName();
            // 判断方法名
            if (methodName.equals("makeText")  /*|| methodName.equals("d")  */  ) {

                PsiMethod method = node.resolve();
                boolean isInClass =  context.getEvaluator().isMemberInClass(method, "android.widget.Toast");
                // 判断是否是 指定类的方法
                if(!isInClass){
                    return;
                }

                // 发送异常报告
                context.report( ISSUE, node,
                        context.getLocation(node),
                        ISSUE.getBriefDescription(TextFormat.TEXT)  );
                JavaLog.showLog("检测到 Toast 使用不规范");
            }
        }
    }


}
